package cn.hsw.platform.filter;

import cn.hsw.platform.core.doc.contants.AuthConstant;
import cn.hsw.platform.core.doc.dto.AuthUserDto;
import cn.hsw.platform.core.doc.util.AuthUtil;
import cn.hsw.platform.core.util.Validator;
import cn.hutool.core.date.DateUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 权限鉴权过滤器
 * @author 李子木
 * @date 2020-12-03
 */
@Component
public class AuthFilter implements GlobalFilter, Ordered {

    Log log = LogFactory.get();

    @Autowired
    AuthUtil authUtil;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        log.error("--------------------------auth filter----------start-----------{}-----", DateUtil.now());

        /*判断是否命中路由*/
        Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);

        Validator.validateNotNull(route,"请求非法,路由未命中");

        /*得到命中的后续服务名称 : hsw-manage*/
        String applicationName = route.getUri().getHost();
        /*判断是否需要鉴权*/
        if(!authUtil.needAuth(applicationName)){
            //不需要鉴权
            log.error("--------------------------auth filter----------not need auth-----------{}-----", DateUtil.now());
            return chain.filter(exchange);
        }
        /*需要鉴权,则获取请求地址*/
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().pathWithinApplication().value();

        /*通过path查询是否需要鉴权*/
        String targetCode = authUtil.getTargetCode(applicationName, path);
        if(Validator.equal(targetCode,AuthConstant.NO_NEED_AUTHENTICATION_DEFAULT_CODE)){
            //不需要鉴权
            log.error("--------------------------auth filter----------not need auth-----------{}-----", DateUtil.now());
            return chain.filter(exchange);
        }

        /*2、需要鉴权则获取用户信息*/
        List<String> tokenList = request.getHeaders().get("token");
        AuthUserDto authUserDto = authUtil.getAuthUser(tokenList);

        /*鉴权*/
        authUtil.authentication(authUserDto.getRolePidList(), targetCode);

        log.error("--------------------------auth filter----------end-----------{}-----", DateUtil.now());
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 10;
    }
}
